<?php

	// +----------------------------------------------------------------------
	// | 后台控制器共有类
	// +----------------------------------------------------------------------
	// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
	// +----------------------------------------------------------------------
	// | Author: 微尘 <yicmf@qq.com>
	// +----------------------------------------------------------------------

	namespace app\common\controller;

	use app\common\middleware\UserAuth;
    use app\common\middleware\UserGetLogin;
    use app\common\middleware\UserSafe;
    use app\common\model\Common as CommonModel;
	use app\event\ucenter\Action as ActionEvent;
	use app\common\event\Base as Event;
	use PhpOffice\PhpSpreadsheet\Spreadsheet;
	use think\Container;
	use think\facade\Db;
	use think\exception\HttpResponseException;
	use think\facade\Cache;
	use think\facade\Config;
	use think\facade\Session;
	use think\Response;
	use think\Model;

	class Admin extends Base
	{

		/**
		 * @var string
		 */
		public $dbname;
		/**
		 * @var string
		 */
		public $validateName;
		/**
		 * @var Base
		 */
		public $event;
		/**
		 * @var CommonModel
		 */
		public $model;

		protected $middleware = [
            UserSafe::class,
            UserAuth::class
        ];
		protected function initialize()
		{
			parent::initialize();
			$this->dbname = strpos($this->request->controller(), '.') ? explode('.', $this->request->controller())[1] : $this->request->controller();
            $this->validateName = $this->dbname;
			$name = '\app\event\\' .request()->auth_module .'\\'. $this->dbname;
			if (class_exists($name)) {
				$this->event = new $name;
			}
		}

		public function delete()
		{
			$result = $this->event->delete($this->request->param(), $this->user);
			if ($result['code'] == 0) {
				$this->_returnSuccess($result['message'], true);
			} else {
				$this->_returnError($result['message']);
			}
		}

		/**
		 * 更新数据
		 * @param Model|Event $object
		 * @param string $action
		 * @author 微尘 <yicmf@qq.com>
		 * @datetime: 2019/12/8 10:23
		 */
		protected function _update($object = null, $action = 'update')
		{
			if ($this->request->isPost()) {
				$result = $this->validate($this->request->post(), $this->validateName);
				if ($result !== true) {
					$this->_returnError('数据验证错误，【' . $result . '】');
				} else {
					if (is_object($object)) {
						$this->event = $object;
					} elseif (is_string($object)) {
						$this->event = new $object;
					}
					$result = $this->event->$action($this->request->post(), $this->user);
					if ($result['code'] == 0) {
						$this->_returnSuccess($result['message'], true);
					} else {
						$this->_returnError($result['message']);
					}
				}
			}
		}


		/**
		 * 空操作，调用对应方法
		 * @author 微尘 <yicmf@qq.com>
		 * @datetime: 2020/6/30 11:33
		 */
		public function _empty()
		{
			if (is_object($this->event)) {
				$action = $this->request->action();
				$result = $this->event->$action($this->request->param(), $this->user);
				if (0 == $result['code']) {
					$this->_returnSuccess($result['message']);
				} else {
					$this->_returnError($result['message']);
				}
			} else {
				$this->_returnError('当前操作未定义');
			}
		}


		/**
		 * 导入Excel表格
		 * @param $file
		 * @return array
		 * @throws \Exception
		 * @author  : 微尘 <yicmf@qq.com>
		 * @datetime: 2019/2/17 12:43
		 */
		protected function excelImport($file)
		{
			if ($file->getInfo()['type'] !== 'application/vnd.ms-excel') {
				throw new \Exception('暂时仅支持Excel2003');
			} else {
				$objReader = \PHPExcel_IOFactory::createReader('Excel5');
				$objPHPExcel = $objReader->load($file->getPathname(), $encode = 'utf-8');
				$sheet = $objPHPExcel->getSheet(0);
				$highestRow = $sheet->getHighestRow(); // 取得总行数
				$col = ord($sheet->getHighestColumn()) - ord('A'); // 取得总列数
				$exc_arr = [];
				for ($i = 1; $i <= $highestRow; $i++) {
					$start = ord('A');
					$temp = [];
					for ($k = 0; $k <= $col; $k++) {
						$temp[] = (string)$objPHPExcel->getActiveSheet()->getCell(chr($start) . $i)->getValue(); //读取类型正常
						$start++;
					}
					$exc_arr[] = $temp;
				}
				return $exc_arr;
			}
		}

		/**
		 * 输出Excel文件.
		 * @param     $fileName 文件名
		 * @param     $headArr  列表头
		 * @param     $data     数据
		 * @return string
		 * @throws \PhpOffice\PhpSpreadsheet\Exception
		 * @author  : 微尘 <yicmf@qq.com>
		 * @datetime: 2019/2/17 10:59
		 */
		protected function excelOut($fileName, $headArr, $data)
		{
			set_time_limit(0);
			// 对数据进行检验
			if (empty($fileName) || empty($headArr) || empty($data)) {
				throw new \Exception('参数不合法');
			}
			$date = date('Y_m_d', time());
			$fileName .= "_{$date}.xlsx";
			$spreadsheet = new Spreadsheet();
			$sheet = $spreadsheet->getActiveSheet();
			//设置表头
			$column = 1;
			$span = ord('A');
			foreach ($headArr as $v) {
				$j = chr($span);
				$sheet->setCellValue($j . $column, $v);
				$span += 1;
			}
			//设置为文本格式
			foreach ($data as $key => $rows) { //行写入
				$column++;
				$span = ord('A');
				foreach (is_object($rows) ? $rows->toArray() : $rows as $keyName => $value) {// 列写入
					$j = chr($span);
					$sheet->setCellValue($j . $column, $value);
					$span++;
				}
			}
			$column = $column + 3;
//			$sheet->setCellValue('A' . $column, 'Power by YiCmf ' . Config::get('yicmf.version'));
			// 设置单元格格式 可以省略
			//        $styleArray = [
			//            'font' => [
			//                'bold' => true,
			//                'size' => 14,
			//            ],
			//        ];
			//        $spreadsheet->getActiveSheet()->getStyle('A1:B1')->applyFromArray($styleArray);
			//        $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(25);
			//        $spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(25);
			//        $spreadsheet->getActiveSheet()->fromArray($data);
//			$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
			$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
			//        header('Content-Description: File Transfer');
			//        header('Expires: 0');
			//        header('Cache-Control: must-revalidate');
			//        header('Pragma: public');
			//        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
			//        header('Content-Disposition: attachment;filename=test.csv');
			//        header('Cache-Control: max-age=0');
			# 浏览器下载
			header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
			header('Content-Disposition: attachment;filename=' . $fileName);
			header('Cache-Control: max-age=0');
			$writer->save('php://output');
			return;
			//        halt($spreadsheet);
			$fp = fopen('php://output', 'a');//打开output流
			mb_convert_variables('GBK', 'UTF-8', $columns);
			fputcsv($fp, $columns);//将数据格式化为csv格式并写入到output流中
			$dataNum = count($arrData);
			$perSize = 1000;//每次导出的条数
			$pages = ceil($dataNum / $perSize);
			for ($i = 1; $i <= $pages; $i++) {
				foreach ($arrData as $item) {
					mb_convert_variables('GBK', 'UTF-8', $item);
					fputcsv($fp, $item);
				}
				//刷新输出缓冲到浏览器
				ob_flush();
				flush();//必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
			}
			fclose($fp);
		}

		protected function _search($dbname = '')
		{
			$map = [];
			$dbname = $dbname ?: $this->request->controller();
			if (false !== strpos($dbname, '.')) {
				$dbname = explode('.', $dbname)[1];
			}
			$cache = 'fields_search_db_' . $dbname;
			if (!Cache::get($cache)) {
				Cache::set($cache, db_get_fields($dbname));
			}
			$params = $this->request->param('field/a');
			if (!empty($params)) {
				foreach ($params as $key => $param) {
//                    dump(Config::get('ucenter.search_like'));
//                    dump(Cache::get($cache));
					if ($param != '' && in_array($key, Cache::get($cache))) {
						if (in_array($key, Config::get('ucenter.search_like'))) {
							$map[$key] = ['like', '%' . trim($param) . '%'];
						} elseif (in_array($key, Config::get('ucenter.search_between_time'))) {
							$param = explode(' - ', $param);
							if ($param[0] && $param[1]) {
								$map[$key] = ['between time', $param];
							}
						} else {
							$map[$key] = $param;
						}
					}
				}
			}
			//            dump($map);
			return $map;
		}

		/**
		 *  后台返回ajax成功
		 * @param string $message
		 * @param false $closeCurrent
		 * @param bool $reload
		 * @param int $wait
		 * @param int $code
		 */
		protected function _returnSuccess($message, $closeCurrent = true, $wait = 3, $reload = true, $code = 0)
		{
			$this->ajax($code, $message, $closeCurrent, $reload, $wait);
		}

		/**
		 *  后台返回ajax成功
		 * @param array $data
		 */
		protected function _returnAuto($data, $closeCurrent = null)
		{
			$this->ajax($data['code'], $data['message'], !is_null($closeCurrent) ? $closeCurrent : 0 == $data['code'], true, 2);
		}
		/**
		 *  后台返回ajax数据
		 * @param string $redirect
		 * @param string $message
		 * @param bool $closeCurrent
		 * @param int $wait
		 */
		protected function _returnRedirect($redirect, $message = null, $closeCurrent = true, $wait = 3)
		{
			$this->ajax(307, $message, $closeCurrent, false, $wait, $redirect);
		}

		/**
		 *  后台返回ajax数据
		 * @param string $redirect
		 * @param string $message
		 * @param bool $closeCurrent
		 * @param int $wait
		 */
		protected function _redirectTab($redirect, $message = null, $closeCurrent = true, $wait = 3)
		{

			$result['message'] = $message;
			$result['url'] = $redirect;
			$result['wait'] = $wait;
			$result['code'] = 307;
			$result['id_md5'] = md5(time());
			$html = app()->getRootPath() . 'app' . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'admin_jump.html';
			$response = Response::create($html, 'view')->assign($result);

			throw new HttpResponseException($response);
		}

		/**
		 *  后台返回ajax数据
		 * @param string $message
		 * @param false $closeCurrent
		 * @param bool $reload
		 * @param int $wait
		 * @param int $code
		 */
		protected function _returnError($message, $closeCurrent = false, $wait = 3, $reload = false, $code = 1)
		{
			$this->ajax($code, $message, $closeCurrent, $reload, $wait);
		}

		/**
		 * 返回请求信息.
		 * @param int $status
		 * @param string $message 返回的提示信息
		 * @param bool string       $closeCurrent 是否关闭当前窗口或者关闭的ID
		 * @param bool string       $reload 刷新当前页面
		 * @param int $wait 等待时间
		 * @author 微尘 <yicmf@qq.com>
		 */
		protected function ajax($status, $message, $closeCurrent = false, $reload = true, $wait = 3, $redirect = '')
		{
			// 记录日志
			if (is_string($message)) {
				ActionEvent::log('admin_operation_log', $this->dbname, [
					'message' => $message,
					'status_code' => $status,
				]);
			}
			$type = $this->getResponseType();

//			if ('html' !== strtolower($type)) {
			if (request()->isPost()) {
				$result['code'] = $status;
				$result['closeCurrent'] = $closeCurrent;
				$result['reload'] = $reload;
				$result['wait'] = $wait;
				$result['message'] = $message;
				$result['redirect'] = $redirect;
				$response = Response::create($result, 'json');
				throw new HttpResponseException($response);
			} else {
				//            $html =
				$response = Response::create('
<title>出错了</title>
<div class="layui-fluid">
  <div class="layadmin-tips">
    <i class="layui-icon" face>&#xe664;</i>
    <div class="layui-text" style="font-size: 20px;">
      ' . $message . '
    </div>
  </div>
</div>
', 'html');
				throw new HttpResponseException($response);
			}
		}

	}
